#include "spi.h"
#include "main.h"
#include "stm32f1xx_hal.h"
#include "stm32f1xx_hal_spi.h"
#include "oled.h"

void SPI_Init(void)
{  
  /*##-1- Enable peripherals and GPIO Clocks #################################*/
  /* Enable GPIO TX/RX clock */


  /*##-2- Configure peripheral GPIO ##########################################*/
  /* SPI SCK GPIO pin configuration  */
  GPIO_InitTypeDef GPIO_InitStruct;
  
  GPIO_InitStruct.Pin       = SPI_SCK_PIN;
  GPIO_InitStruct.Mode      = GPIO_MODE_OUTPUT_PP;
	// GPIO_InitStruct.Pull      = GPIO_PULLDOWN;
  GPIO_InitStruct.Speed     = GPIO_SPEED_FREQ_HIGH;
  HAL_GPIO_Init(SPI_SCK_GPIO_PORT, &GPIO_InitStruct);
  HAL_GPIO_WritePin(SPI_SCK_GPIO_PORT, SPI_SCK_PIN, GPIO_PIN_RESET);

  /* SPI MOSI GPIO pin configuration  */
  GPIO_InitStruct.Pin = SPI_MOSI_PIN;
  GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
  HAL_GPIO_Init(SPI_MOSI_GPIO_PORT, &GPIO_InitStruct);
  HAL_GPIO_WritePin(SPI_MOSI_GPIO_PORT, SPI_MOSI_PIN, GPIO_PIN_RESET);
  
  GPIO_InitStruct.Pin = SPI_CLR_PIN;
  GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
  HAL_GPIO_Init(SPI_CLR_GPIO_PORT, &GPIO_InitStruct);
  HAL_GPIO_WritePin(SPI_CLR_GPIO_PORT, SPI_CLR_PIN, GPIO_PIN_SET);
	
	
	
	GPIO_InitStruct.Pin = SDO_Pin;
  GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
  GPIO_InitStruct.Pull = GPIO_NOPULL;
//	GPIO_InitStruct.Speed     = GPIO_SPEED_FREQ_HIGH;
  HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);
}


unsigned char AD5724R_Init(void){
	  SPI_Init();
	//LDAC'保持高电平
    LDAC_L;
	//SYNC'保持高电平
	  SYNC_H;
	  CLR_H;
	
}


void AD5724R_SetRegisterValue(uint8_t r1,uint8_t r2,uint8_t r3){
     unsigned char rw[3] = {0};
	   SYNC_L;
		 rw[0] = r1;
		 rw[1] = r2;
		 rw[2] = r3;
		 for(int i = 0;i<3;i++)
		   simulate_spi_write_byte(rw[i]);
		 SYNC_H;
}

unsigned char AD5724R_GetRegisterValue(uint8_t r1,uint8_t r2,uint8_t r3){
     unsigned char rw[3] = {0};
		 unsigned char data[3] = {0};
		 rw[0] = r1;
		 rw[1] = r2;
		 rw[2] = r3;
		 for(int i = 0;i<3;i++){
			 simulate_spi_write_byte(rw[i]);
		   data[i] = simulate_spi_read_byte();
		 }
		 
}

void AD5724R_SetPower(unsigned char dacChannel){
	    u8 r1,r2,r3;
	    //默认4通道全部开启
			r1 = 0x10,r2 = 0x00,r3 = 0x0f;
	    r3 = dacChannel & r3;
      AD5724R_SetRegisterValue(r1,r2,r3);
}


void AD5724R_RangeSelect(){
      u8 r1,r2,r3;
	    //默认4通道全部开启
			r1 = 0x0c, r2 = 0x00, r3 = 0x04;
      AD5724R_SetRegisterValue(r1,r2,r3);
}


void AD5724R_LoadDac(unsigned char dacChannel, int dacValue){
	   u8 r1,r2,r3;
		 r1 = 0x04, r2 = 0xff, r3 = 0xf0;
	   r1 = r1 &   dacChannel;
	   r2 = r2 &   (dacValue>>4);
	   r3 = r3 &   (dacValue<<4);
	   AD5724R_SetRegisterValue(r1,r2,r3);

}

void simulate_spi_write_byte(u8 data)
{
     u8 kk;
     SCK_L;
     SIMULATE_DELAY_US;     //读取第一bit数据 等待数据稳定 根据实际时钟调整
     SIMULATE_DELAY_US;
	   SIMULATE_DELAY_US;
    //大概的spi时钟为1/2us=500KHZ   左右
    for(kk=0;kk<8;kk++)
    {
     //高位在前发送方式    根据升级器件特性定
    if((data&0x80)==0x80) MOSI_H;
    else         MOSI_L;
    SIMULATE_DELAY_US;      //等待数据稳定  根据实际时钟调整
    SCK_H;//上升沿发送数据
    SIMULATE_DELAY_US;//CLK高电平保持一段时间 这个可以不需要 根据具体的spi时钟来确定
    SCK_L; //把时钟拉低实现为下一次上升沿发送数据做准备
    data = data<<1;//发送数据的位向前移动一位
    }

}

u8 simulate_spi_read_byte(void)
{
    u8 kk=0, ret=0;
    SCK_L;
	  SIMULATE_DELAY_US;     //读取第一bit数据 等待数据稳定 根据实际时钟调整
	  SIMULATE_DELAY_US;
	  SIMULATE_DELAY_US;
    //大概的spi时钟为1/2us=500KHZ   左右
    for(kk=0;kk<8;kk++)
    {
	  ret = ret<<1; //读的时候 高位在前   根据升级器件特性定
    SIMULATE_DELAY_US;
    SCK_H; //上升沿读取数据
		SIMULATE_DELAY_US;
    if(MISO) ret |= 0x01;
    SCK_L;//标识数据接收完毕
    }

    return ret;
}